<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /* 展开语法 */
        let a1=[1,2,3,'a','b','c'];
        let b1=[...a1,'哈哈哈','真好'];
        console.log("展开语法:"+b1);//展开语法:1,2,3,a,b,c,哈哈哈,真好

        /* 解构赋值 */
        let [a2,b2]=['赋值给a2','赋值给b2'];
        console.log(`数组解构：${a2}。${b2}`);//数组解构：赋值给a2。赋值给b2
        let {a22,b22}={'a22':'赋值给a22','b22':'赋值给b22'};
        console.log(`对象解构：${a22}。${b22}`);//对象解构：赋值给a22。赋值给b22


        /* 剩余解构 */
        let [a3,...b3]=['赋值给a3','b3的','还是b3的','还是b3的'];
        console.log(`剩余解构：${a3}。${b3}`);//剩余解构：赋值给a3。b3的,还是b3的,还是b3的

        /* 增删改查、排序、过滤、迭代 */
        
        //数组后面压入:push
        let a4=[1,2,3];
        a4.push('压入1','压入2');
        console.log(`数组后面压入:${a4}`);//数组后面压入:1,2,3,压入1,压入2

        //数组后面弹出:pop
        let a5=[1,2,3];
        a5.pop()
        console.log(`数组后面弹出:${a5}`);//数组后面弹出:1,2

        //数组前面压入:unshift
        let a6=[1,2,3];
        a6.unshift('压入1','压入2');
        console.log(`数组前面压入:${a6}`);//数组前面压入:压入1,压入2,1,2,3

        //数组前面弹出:shift
        let a7=[1,2,3];
        a7.shift();
        console.log(`数组前面弹出:${a7}`);//数组前面弹出:2,3

        //数组复制:slice
        let a8=[1,2,3];
        let b8=a8.slice();//全部复制
        let c8=a8.slice(1,2);//左闭右开[1,2)，不传第二个参数时默认复制到最后
        console.log(`数组复制a8:${a8}。b8:${b8}`);//数组复制a8:1,2,3。b8:1,2,3
        console.log(`数组按需复制:${c8}`);//数组按需复制:2

        //数组按需增删改：splice(从哪开始删除，删除数量，添加)
        let a9=[1,2,3,4,5];
        a9.splice(1,2);//从下标为1开始，往后删除2个
        console.log(`splice删除：${a9}`);//splice删除：1,4,5

        let a10=[1,2,3,4,5];
        a10.splice(1,2,'好','靓仔','哈好好');//不管后面有多少个，都是要增进去的
        console.log(`splice先删后增:${a10}`);//splice先删后增:1,好,靓仔,哈好好,4,5

        //清空数组
        let a11=[1,2,3];
        a11=[];//清空
        console.log("清空："+a11);

        //合并拆分
        //合并：通过什么合并
        let a12=[1,'a','还好',2];
        //合并后从一个object对象类型变成了一个string字符类型
        console.log(`合并:${a12.join('')}`);//合并:1a还好2
        console.log(`合并:${a12.join('-')}`);//合并:1-a-还好-2
        //拆分：通过什么拆开
        let a13="123,abc";
        console.log(`拆分：${a13.split(',')}`);//拆分：123,abc,1ac,3cb
        console.log(`拆分：${a13.split('c')}`);//拆分：123,ab,,1a,,3,b
        //先拆再反转后合并
        let a14="123abc";
        console.log(`先拆再反转后合并:${a14.split('').reverse().join('-')}`);//先拆再反转后合并:c-b-a-3-2-1

        //查
        let a15=[1,2,3,'a','b','c'];
        
        //返回元素的下标，查不到返回-1 
        //从前往后查：indexOf,查找元素出现的位置(就算元素重复，但我查到第一个之后就把它的下标返回，常用于过滤)
        console.log("indexOf从前往后查:"+a15.indexOf(3));//indexOf从前往后查:2
        console.log("indexOf从前往后查:"+a15.indexOf('b'));//indexOf从前往后查:4
        console.log("indexOf从前往后查(第二个参数指定从哪里开始查):"+a15.indexOf('b',3));//indexOf从前往后查(第二个参数指定从哪里开始查):4
        console.log("indexOf从前往后查(查不到):"+a15.indexOf(5));//indexOf从前往后查(查不到):-1
        //从后往前查：lastIndexOf
        console.log("lastIndexOf从后往前查:"+a15.lastIndexOf(3));//lastIndexOf从后往前查:2
        console.log("lastIndexOf从后往前查:"+a15.lastIndexOf('b'));//lastIndexOf从后往前查:4
        console.log("lastIndexOf从后往前查(第二个参数指定从哪里开始查):"+a15.lastIndexOf('b',3));//lastIndexOf从后往前查(第二个参数指定从哪里开始查):-1
        console.log("lastIndexOf从后往前查(查不到):"+a15.lastIndexOf(5));//lastIndexOf从后往前查(查不到):-1
  
        //返回布尔值includes，不能查找引用类型比如：对象、数组
        console.log("includes返回布尔值："+a15.includes('a'));//includes返回布尔值：true
        const a16 = [{ name: "李四" }, { name: "张三" }, { name: "qq" }];
        const includes = a16.includes({ name: "qq" });
        console.log(includes);//false

        //返回具体值：find，可以方便的查找引用类型
        /*
            find()方法，用于找出第一个符合条件的数组成员。它的参数是一个回调函数，所有数组成员依次执行该回调函数，
            直到找出第一个返回值为true的成员，然后返回该成员。如果没有符合条件的成员，则返回undefined。

            findIndex()方法的用法与find()方法非常类似，返回第一个符合条件的数组成员的位置，
            如果所有成员都不符合条件，则返回-1。
        */
        const a17 = [{ name: "李四" }, { name: "张三" }, { name: "qq" }];
        const b17=[1,2,5,6,-2,-3];
        const find1 = a17.find(a17 => (a17.name == "张三"));//查找数组对象中名字为"张三"的对象
        const find2 = b17.find(b17=> b17 < 0);//查找数组中小于0的第一个值
        const find3 = b17.findIndex(b17=> b17 < 0);//查找数组中小于0的第一个值的下标
        console.log(find1);//{name: '张三'}
        console.log(find2);//-2
        console.log(find3);//4

        //排序sort
        let a18 = [1,4,3,6,8];
        let lessons = [
                        { title: "媒体查询响应式布局", click: 78 },
                        { title: "FLEX 弹性盒模型", click: 12 },
                        { title: "MYSQL多表查询随意操作", click: 99 }
                      ];
        console.log("默认从小到大："+a18.sort());//默认从小到大：1,3,4,6,8
        //参数一与参数二比较，返回 正数:降序。负数：升序
        console.log("正数降序："+a18.sort((a,b) => b-a ));//降序：8,6,4,3,1
        console.log("负数升序："+a18.sort((a,b) => a-b ));//升序：1,3,4,6,8
        console.log(lessons.sort((a,b) => a.click - b.click ));

        //遍历
        let a19 = [
                    {title: '媒体查询响应式布局',category: 'css'},
                    {title: 'FLEX 弹性盒模型',category: 'css'},
                    {title: 'MYSQL多表查询随意操作',category: 'mysql'}
                  ];
        //for循环
        let b19=[];
        for (let i = 0; i < a19.length; i++) {
            b19[i]=a19[i].title;//下标也对应起来，相当于浅拷贝了
        }
        console.log("for循环：");
        console.log(b19);//['媒体查询响应式布局', 'FLEX 弹性盒模型', 'MYSQL多表查询随意操作']    

        //forEach:forEach使函数作用在每个数组元素上，但是没有返回值。
        console.log("forEach：");
        a19.forEach((item,index,array)=>{//(元素，下标,数组整体本身)
            console.log(item);
            /*
                {title: '媒体查询响应式布局', category: 'css'}
                {title: 'FLEX 弹性盒模型', category: 'css'}
                {title: 'MYSQL多表查询随意操作', category: 'mysql'}
            */
        })

        //for...in...
        console.log("for...in...：");
        for(const key in a19){//key为下标索引
            console.log(key+':'+a19[key].title);
            /*
                0:媒体查询响应式布局
                1:FLEX 弹性盒模型
                2:MYSQL多表查询随意操作
            */
        }

        //for...of...
        console.log("for...of...:");
        for(const item of a19){//item为元素值
            console.log(item);
            /*
                {title: '媒体查询响应式布局', category: 'css'}
                {title: 'FLEX 弹性盒模型', category: 'css'}
                {title: 'MYSQL多表查询随意操作', category: 'mysql'}
            */
        }


        //迭代,通过遍历辅助迭代的执行
        //获取索引：keys
        console.log("迭代下标索引keys:");
        const a20 = ["a", "b", "c"];
        for (const key of a20.keys()) {
            console.log(key);//0 1 2
        }
        //获取值：values
        console.log("迭代值values:");
        for(const item of a20.values()){//其实用了for..of迭不迭代item都是值，values()就没有存在的必要了
            console.log(item);//a b c
        }
        //获取键和值：entries
        console.log("迭代键值对entries:");
        for(const [k,v] of a20.entries()){
            console.log(k,v);
            /*
                0 'a'
                1 'b'
                2 'c'
            */
        }

        //过滤
        //filter
        /*
            filter 为数组中的每个元素调用一次 callback 函数，并利用所有使得 callback 返回 true 或 等价于 true 的值 的元素创建一个新数组。
            那些没有通过 callback 测试的元素会被跳过，不会被包含在新数组中。
            filter 不会改变原数组。
        */
        console.log("过滤器：");
        let a21=[1,5,2,5,2,8,12,16];
        let b21=a21.filter(item=>item>10);//为true的就把它拿出来
        let c21=a21.filter((item, index, array)=>{
            /*
                indexOf用于查找元素出现的位置，为0 1 2 1 2 5 6 7
                index为元素下标，为0 1 2 3 4 5 6 7
            */
            return array.indexOf(item) === index;//数组去重
        });
        console.log(b21);//[12, 16]
        console.log(c21);//[1, 5, 2, 8, 12, 16]

    </script>
</body>
</html>